#pragma once 
#include <vector>
#include <string>
#include <map>
#include <memory>

enum tv_tok_type_e {
	TT_RESET,
	TT_SET,
	TT_RUNS_ON,
	TT_POP,
	TT_PUSH,
	TT_IF,
	TT_EMPTY,
	TT_LINE_INDEX,
	TT_VERIFY,
	TT_CALL,
	TT_REQUIRE,
	TT_SOME,
	TT_ONE,
	TT_SCOPE_OPEN,
	TT_SCOPE_CLOSE,
	TT_WHITESPACE,
	TT_IS,
	TT_IS_NOT,
	TT_QUEUE_,
	TT_EVENT_,
	TT_FUNC_,
	TT_COND_,
	TT_THREAD_,

	// external instructions
	TT_ON_STEP,
	TT_ON_IDLE,

	TT_FUNC_GEN,
	TPSEUDO_COND,
};
struct tv_token_s {
	tv_tok_type_e type;
	std::string arg_str;
	int arg_int;
	std::string to_string() const;
};
struct tv_line_s {
	void parse(char const * text);
	bool null() const;
	bool validate();
	std::vector< tv_token_s > tokens;
	std::string raw;
	int line_index;
};
struct tv_instructions_s {
	~tv_instructions_s();
	tv_line_s header;
	std::vector<tv_line_s> lines;
};
struct tv_result_s {
	std::vector< std::string > errors;
};
class tv_meta_c {
	std::map< int, std::vector< std::shared_ptr< tv_instructions_s > > > var_entry_points;
	std::map< std::string, std::shared_ptr< tv_instructions_s > > var_named_functions;
	std::vector< std::shared_ptr< tv_instructions_s > > var_conditions;
	std::vector< int > var_idle;
	std::vector< int > var_always;
	tv_result_s var_result;
public:
	class context_c {
		class thread_c;
		tv_meta_c * var_meta;
	public:
		context_c(tv_meta_c * meta);
		~context_c();

		tv_result_s run(int time_in_seconds);
	};
	void parse_file(char const * filename);
private:
	void _add_entrypoints(std::shared_ptr< tv_instructions_s > func);

};